<?php

namespace api\coupon;

use app\common\model\Goods;
use app\model\CouponOrder;
use app\model\GoodsNotify;
use think\facade\Db;

/**
 * 重庆璐付.
 * 
 * http://www.jiaofei100.com/open/jiaofei100API.html#21
 */
class Jiaofei100
{
    private $id;
    private $url;
    private $apiId;
    private $apiKey;
    private $error;

    protected $statusMsg = [
        10007 => '参数错误！',
        10008 => '订单超时！',
        10009 => '参数校验错误！',
        10010 => '代理商 ID 不存在！',
        10011 => '订单号长度大于 36！',
        10012 => '代理商状态错误',
        10013 => '账户余额不足',
        10014 => 'IP 地址验证失败',
        10015 => '充值号码有误',
        10016 => '暂不支持该号码',
        10017 => '禁止采购该商品',
        10018 => '订单提交成功',
        10020 => '订单提交失败',
        10021 => '未知错误',
        10022 => '订单号重复',
        10023 => '暂不支持该面值',
        10025 => '订单处理中',
        10026 => '交易失败',
        10027 => '交易成功',
        10029 => '订单不存在',
        10035 => '限制5分钟内同一时间和同一个金额',
        10036 => '系统维护',
        10037 => '活动未开始',
        10038 => '活动已结束',
    ];

    public function __construct($info)
    {
        $this->id = $info['id'];
        // if (function_exists('doLog')) {
        //     doLog('info，'.json_encode($info));
        // }
        $config = is_string($info['api_config']) ? json_decode($info['api_config'], true) : $info['api_config'];
        $this->url = rtrim($config['url'], '/');
        $this->apiId = trim($config['api_id']);
        $this->apiKey = trim($config['api_key']);
    }

    /**
     * 视频接口
     * @param $data
     * @return mixed
     */
    public function createVideo($data)
    {
        //        $res = [
        //            'Code' => '10018',
        //            'Msg' => '订单提交成功',
        //            'ReturnOrderID' => '60672247710407152653',
        //            'TradingID' => '60672247710407152653',
        //        ];
        //        return $res;

        $url = $this->url . '/Api/PayVideo.aspx';

        $orderId = $data['order_id'] ?? '';

        $params = [
            'APIID' => $this->apiId,
            'Account' => $data['account'],   // 充值账号
            'BuyNum' => 1,
            'CreateTime' => date("YmdHis"),
            'IsCallBack' => 1,
            'OrderID' => $orderId,
            'ProductCode' => $data['sku_id'],
        ];

        $sign = $this->getSign($params);
        $params['Sign'] = $sign;
        $params['CallBack'] = env('app.api_url') .  '/api/notifyV2/jiaofeiCouponNotify';
        $result = curlPost($url, $params);
        $res = json_decode($result, true);
        return $res;
    }

    /**
     * 游戏/卡密/卡券充值
     * @param $data
     * @return mixed
     */
    public function createCard($data)
    {
        $url = $this->url . '/Api/PayGame.aspx';
        $params = [
            'APIID' => $this->apiId,
            'Account' => $data['account'],
            'BuyNum' => 1,
            'ClientIP' => $data['api_ip'],
            'CreateTime' => date("YmdHis"),
            'GoodsID' => $data['sku_id'],
            'isCallBack' => 1,
            'OrderID' => $data['order_id'],
            'TotalPrice' => $data['market_price'] * 10,
            'TradeType' => $data['trade_type'],
            'UnitPrice' => $data['market_price'] * 10,
        ];
        $sign = $this->getSign($params);
        $params['Sign'] = $sign;
        $params['CallBack'] = env('app.api_url') .  '/api/notifyV2/jiaofeiCouponNotify';
        $result = curlPost($url, $params);
        $res = json_decode($result, true);
        return $res;
    }

    /**
     * 查询余额.
     *
     * 单位：分
     */
    public function queryAmount()
    {
        $sign = strtoupper(md5(http_build_query([
            'APIID' => $this->apiId,
            'APIKEY' => $this->apiKey,
        ])));
        $params = [
            'APIID' => $this->apiId,
            'Sign' => $sign,
        ];
        $url = $this->url . '/Api/GetUserMoney.aspx';
        $res = curlPost($url, $params);

        // 日志记录
        if (function_exists('doLog')) {
            doLog('重庆璐付查询余额请求日志，' . $url . '，返回' . $res);
        }
        $res = json_decode($res, true);
        if (!isset($res['Money'])) {
            $this->error = $res['Msg'] ?? '查询频繁';

            return false;
        }

        return yuan2fen($res['Money']);
    }

    /**
     * 订单回调
     * @param $params
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function notify($params)
    {
        $tip = 'success';
        $orderId = $params['OutID'] ?? '';
        $insertData = [];

        if (!isset($params['OutID']) && !isset($params['State'])) {
            $insertData['result'] = '参数不合法';
            GoodsNotify::addGoods($params, $insertData, $orderId, 2);
            return $tip;
        }

        $order = CouponOrder::where([
            'status' => CouponOrder::C_STATUS_SUBMIT,
            'order_id' => $orderId
        ])->find();
        if (!$order) {
            $insertData['result'] = '订单不存在';
            GoodsNotify::addGoods($params, $insertData, $orderId, 2);
            return $tip;
        }

        $cardInfo = $params['OrderInfo'] ?? [];
        $code = $params['State'];

        $update = [];

        if ('10027' == $code) {
            $update['status'] = CouponOrder::C_STATUS_RECHARGE_SUCCESS;
        } elseif ('10025' == $code) {
            $update['status'] = CouponOrder::C_STATUS_PROCESSING;
        } else {
            $update['status'] = CouponOrder::C_STATUS_RECHARGE_FAIL;
        }

        $update['status_msg'] = $this->statusMsg[$code] ?? '';
        $update['card_info'] = $cardInfo ? json_encode($cardInfo, true) : '';

        $insertData = [
            'order_id' => $orderId,
            'result' => 'success',
        ];

        GoodsNotify::addGoods(json_encode($params), $insertData, $orderId, 2);

        Db::startTrans();
        try {
            $res = Goods::handleNotify($order, $update);
            if (empty($res)) {
                throw new \Exception('更新失败');
            }

            Db::commit();
        } catch (\Exception $e) {
            $insertData['result'] = '订单更新失败' . $order->id . '。' . $e->getMessage();
            Db::rollback();
            GoodsNotify::addGoods(json_encode($params), $insertData, $orderId, 2);
            $tip = 'fail';
        }

        return $tip;
    }

    public function getError()
    {
        return $this->error;
    }

    /**
     * 生成签名
     * @param $params
     * @return string
     */
    public function getSign($params)
    {
        if (isset($params['sign'])) {
            unset($params['sign']);
        }
        // 拼接签名串
        $sign_str = http_build_query($params) . '&APIKEY=' . $this->apiKey;
        // 签名
        $sign = strtoupper(md5(urldecode($sign_str)));

        return $sign;
    }
}
